使用声明
当某个名字在它自己的名字空间之外频繁使用时,在反复写它的时候都要加上有关名字空间作为限定词,这样做也会变成很令人厌烦的事情。考虑
double Parser::prim(bool get) // 处理初等项
{
if(get) Lexer::get_token();
switch(Lexer::curr_tok) {
case Lexer::NUMBER: // 浮点常量
Lexer::get_token();
return Lexer::number_value;
case Lexer::NAME:
{
double& v = table[Lexer::string_value];
if(Lexer::get_token() == Lexer::ASSIGN) v = expr(true);
return v;
}
case Lexer::MINUS: // 一元减
return -prim(true);
case Lexer::LP:
{
double e = expr(true);
if(Lexer::curr_tok != Lexer::RP) return Error::error(") expected");
Lexer::get_token(); // 吃掉 ')'
return e;
}
case Lexer::END:
return 1;
default:
return Error::error("primary expected");
}
}
反复写限定词Lexer很讨厌,也会分散人的注意力。这种多余的东西可以通过一个使用声明而清除掉,只需要在某个地方说明,在这个作用域里所用的get_token就是Lexer的get_token。例如,
double Parser::prim(bool get) // 处理初等项
{
using Lexer::get_token; // 使用Lexer的get_token
using Lexer::curr_tok; // 使用Lexer的curr_tok
using Error::error; // 使用Error的error
if(get) get_token();
switch(curr_tok) {
case Lexer::NUMBER: // 浮点常量
get_token();
return Lexer::number_value;
case Lexer::NAME:
{
double& v = table[Lexer::string_value];
if(get_token() == Lexer::ASSIGN) v = expr(true);
return v;
}
case Lexer::MINUS: // 一元减
return -prim(true);
case Lexer::LP:
{
double e = expr(true);
if(curr_tok != Lexer::RP) return error(") expected");
get_token(); // 吃掉 ')'
return e;
}
case Lexer::END:
return 1;
default:
return error("primary expected");
}
}
使用声明将引进局部的同义词。
将同义词尽可能地保持在局部中以避免混乱,这是一种很好的想法。由于所有分析函数都使用差不多同样的一集来自其他模块的名字,我们也可以把有关的使用声明放在Parser名字空间的定义里:
namespace Parser {
double prim(bool);
double term(bool);
double expr(bool);
using Lexer::get_token; // 使用Lexer的get_token
using Lexer::curr_tok; // 使用Lexer的curr_tok
using Error::error; // 使用Error的error
}
这就使我们能将Parser函数简化到几乎等同于原来的版本了:
double Parser::term(bool get) // 乘和除
{
double left = prim(get);
for(;;)
switch(curr_tok) {
case Lexer::MUL:
left *= prim(true);
break;
case Lexer::DIV:
if(double d = prim(true)) {
left /= d;
break;
}
return error("divide by 0");
default:
return left;
}
}
也可以将各个单词的名字引进Parser名字空间。然而我还是采用带显式限定词的形式把它们放在那里,以帮助我们记住Parser依赖于Lexer。
🔚